package com.vpen.chat.server.handler;

import cn.hutool.core.date.LocalDateTimeUtil;
import io.netty.channel.*;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.ChannelMatcher;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;

/**
 * 描述
 *
 * @author 韦鹏
 * @date 2022/11/15 15:46
 */
@Slf4j
public class ChatHandler extends SimpleChannelInboundHandler<String> {

    //    定义个channel组，管理所有的channel,本质上是一个Set集合
    private final static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    /**
     * 连接建立被触发
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        boolean success = channelGroup.add(channel);
//        推送成功就通知其它的客户端
        if (success) {
            // 该group会将循环所有的客户端并通知
            channelGroup.writeAndFlush(LocalDateTimeUtil.now() + "[客户端]" + channel.remoteAddress() + "加入聊天");
        }

    }

    /**
     * channel处于活动状态
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.debug(LocalDateTimeUtil.now() + "[客户端]{}上线了", ctx.channel().remoteAddress());
    }

    /**
     * channel处于非活动状态
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.debug(LocalDateTimeUtil.now() + "[客户端]{}离线了", ctx.channel().remoteAddress());
    }

    /**
     * 断开连接
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        // 不需要手动remove
        //boolean success = channelGroup.remove(channel);
        // 该group会将循环所有的客户端并通知
        channelGroup.writeAndFlush(LocalDateTimeUtil.now() + "[客户端]" + channel.remoteAddress() + "离开聊天");

    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        Channel channel = ctx.channel();
        msg = LocalDateTimeUtil.now() + "[客户端]" + channel.remoteAddress() + "发送: " + msg;
        // 除了自己，推送给所有的客户端
        channelGroup.writeAndFlush(msg, ch -> !(channel == ch));
    }
}
